package com.example.mgs.Service.Impl;

import com.aliyun.oss.ServiceException;
import com.example.common.constants.FileConstants;
import com.example.common.utils.AliOssUtil;
import com.example.common.utils.CacheClient;
import com.example.mgs.Mgs.FileMergeTask;
import com.example.mgs.Service.FileService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.*;
import java.util.Arrays;

@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Autowired
    private AliOssUtil aliOssUtil;
    @Autowired
    private CacheClient cacheClient;

    // 临时文件存储目录
    private final String TEMP_DIR = System.getProperty("user.dir") + "/temp/file-chunks/";


    @PostConstruct
    public void init() {
        // 确保临时目录存在
        File dir = new File(TEMP_DIR);
        if (!dir.exists()) {
            log.info("创建临时目录：{}", TEMP_DIR);
            dir.mkdirs();
        }
    }

    @Override
    public void saveChunk(String taskId, Integer chunkIndex, byte[] data) throws FileNotFoundException {
        try {
            String filePath = getTempFilePath(taskId, chunkIndex);
            File file = new File(filePath);
            // 确保父目录存在
            File parentDir = file.getParentFile();
            if (!parentDir.exists()) {
                parentDir.mkdirs();
            }
            // 写入分片数据
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(data);
            fos.close();
            log.info("保存分片成功: {}", filePath);
        } catch (IOException e) {
            log.error("保存分片失败, taskId={}, chunkIndex={}", taskId, chunkIndex, e);
            throw new ServiceException("保存分片失败");
        }
    }

    @Override
    public byte[] mergeChunks(String taskId, Integer totalChunks) {
        try {
            // 计算合并后的文件大小
            long totalSize = 0;
            for (int i = 0; i < totalChunks; i++) {
                File chunkFile = new File(getTempFilePath(taskId, i));
                totalSize += chunkFile.length();
            }
            // 创建合并后的文件
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) totalSize);
            byte[] buffer = new byte[8192];
            // 按顺序合并所有分片
            for (int i = 0; i < totalChunks; i++) {
                File chunkFile = new File(getTempFilePath(taskId, i));
                FileInputStream fis = new FileInputStream(chunkFile);

                int len;
                while ((len = fis.read(buffer)) != -1) {
                    bos.write(buffer, 0, len);
                }
                fis.close();
            }
            return bos.toByteArray();
        } catch (IOException e) {
            log.error("合并分片失败, taskId={}", taskId, e);
            throw new ServiceException("合并分片失败");
        }
    }

    @Override
    public void deleteChunk(String taskId) {
        try {
            File taskDir = new File(TEMP_DIR + taskId);
            if (taskDir.exists() && taskDir.isDirectory()) {
                File[] files = taskDir.listFiles();
                if (files != null) {
                    for (File file : files) {
                        file.delete();
                    }
                }
                taskDir.delete();
                log.info("删除临时文件成功, taskId={}", taskId);
            }
        } catch (Exception e) {
            log.error("删除临时文件失败, taskId={}", taskId, e);
            // 不抛出异常，避免影响主流程
        }
    }

    @Override
    public FileMergeTask getTaskFromRedis(String taskId) {
        return cacheClient.get(FileConstants.FILE+taskId, FileMergeTask.class);
    }

    @Override
    public void updateTaskInRedis(FileMergeTask task) {
        cacheClient.set(FileConstants.FILE+task.getTaskId(), task);
    }

    @Override
    public void save(FileMergeTask task) throws Exception {
        cacheClient.set(FileConstants.FILE+task.getTaskId(), task);
    }

    @Override
    public void deleteTaskFromRedis(String taskId) {
         cacheClient.delete(FileConstants.FILE+taskId);
    }


    @Override
    public Integer getUploadedChunkCount(String taskId) {
        File taskDir = new File(getTempFilePath(taskId, 0).replace("/0.chunk", ""));
        if (!taskDir.exists() || !taskDir.isDirectory()) {
            return 0;
        }

        File[] chunks = taskDir.listFiles();
        if (chunks == null) {
            return 0;
        }

        // 过滤出有效的分片文件
        return (int) Arrays.stream(chunks)
                .filter(file -> file.getName().matches("\\d+\\.chunk"))
                .count();
    }

    @Override
    public String getTempFilePath(String taskId, Integer chunkIndex) {
        return TEMP_DIR + taskId + "/" + chunkIndex + ".chunk";
    }

    @Override
    public String getFileExtension(String fileName) {
        if (fileName == null || !fileName.contains(".")) {
            return "bin"; // 默认二进制文件
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    }
}
